package com.hubu.file;


import java.io.*;
import java.util.*;

/**
 *
 *
 *
 *
 * 文件拆分
 */
public class FileSplit {

    private int log=0;
    private int count=0;
    private Map<Integer,List<String>> map=new HashMap<>();
    private int fileSize=4096;
    private static final String WRITE_FILE_PATH_PREFIX="write_file_index_";
    public void splitFileByHash(String sourcePath,String targetPath){
        File file=new File(sourcePath);
        if(!file.exists()||file.isDirectory()){
            throw new RuntimeException("文件必须存在并且不能是文件夹");
        }
        FileInputStream fileInputStream=null;
        BufferedReader bufferedReader=null;

        InputStreamReader inputStreamReader=null;

        try {
            fileInputStream=new FileInputStream(file);
            inputStreamReader =new InputStreamReader(fileInputStream);
            bufferedReader=new BufferedReader(inputStreamReader);
            while(true){
                try {
                    String s = bufferedReader.readLine();
                    if(s==null){
                        break;
                    }
                    int hashIndex=hashFunction(s,fileSize);
                    if(map.containsKey(hashIndex)){
                        List<String> list = map.get(hashIndex);
                        list.add(s);
                        count++;
                    }
                    else{
                        List<String> list=new ArrayList<>();
                        list.add(s);
                        count++;
                        map.put(hashIndex,list);
                    }

                    if(count>=300000){
                        System.out.println("写文件");
                        writeMapToFile((HashMap<Integer, List<String>>) map,targetPath);
                        map.clear();
                        count=0;
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            if(bufferedReader!=null){
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(inputStreamReader!=null){
                try {
                    inputStreamReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(fileInputStream!=null){
                try {
                    inputStreamReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void writeMapToFile(HashMap<Integer, List<String>> map,String targetPath) {
        Set<Integer> integers = map.keySet();
        Iterator<Integer> it = integers.iterator();
        while(it.hasNext()){
            Integer next = it.next();
            List<String> list = map.get(next);
            //将所有数据写到file中
            writeListToFile(targetPath+WRITE_FILE_PATH_PREFIX+next,list);
        }
    }


    public void writeListToFile(String filePath,List<String> list){
        File file=new File(filePath);
        FileOutputStream  fileOutputStream=null;
        BufferedWriter bufferedWriter=null;

        OutputStreamWriter outputStreamWriter=null;

        try {
            fileOutputStream=new FileOutputStream(file,true);
            outputStreamWriter =new OutputStreamWriter(fileOutputStream);
            bufferedWriter=new BufferedWriter(outputStreamWriter);


            try {
                for(int i=0;i<list.size();i++){
                    bufferedWriter.write(list.get(i)+"\n");
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            if(bufferedWriter!=null){
                try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(outputStreamWriter!=null){
                try {
                    outputStreamWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(fileOutputStream!=null){
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public void writeStringToFile(String filePath,String text){
        File file=new File(filePath);
        FileOutputStream  fileOutputStream=null;
        BufferedWriter bufferedWriter=null;

        OutputStreamWriter outputStreamWriter=null;

        try {
            fileOutputStream=new FileOutputStream(file,true);
            outputStreamWriter =new OutputStreamWriter(fileOutputStream);
            bufferedWriter=new BufferedWriter(outputStreamWriter);
            try {
                bufferedWriter.write(text+"\n");
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            if(bufferedWriter!=null){
                try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(outputStreamWriter!=null){
                try {
                    outputStreamWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(fileOutputStream!=null){
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public int  hashFunction(String value,int fileSize){
        return value.hashCode()&(fileSize-1);
    }
    public static void main(String[] args) {
        FileSplit fileSplit = new FileSplit();
        fileSplit.splitFileByHash("d:\\data2\\data.txt","D:\\data2\\data3\\");
    }

}
